<template>
  <el-scrollbar
    class="mb-tree"
    v-loading="loading"
    @click="handleClearSelect"
  >
    <el-tree
      ref="mbtreeRef"
      class="menu-custom-tree"
      style="--el-tree-node-content-height: 36px;"
      :data="apps"
      node-key="id"
      :highlight-current="true"
      :default-expanded-keys="expandedKeys"
      :props="treeSetting"
      @click.native.stop="empty"
      @node-click="handleClick"
    >
      <template #default="{ node, data }">
        <span
          class="menu-custom-tree-node p-2"
          style="position: relative;overflow: hidden;">
          <span
            class="menu-custom-icon"
            :class="{ 'menu-root-icon': !isTask(data), 'menu-icon-module': isTask(data) }">
            <JIcon :icon="DFT_ICONS.platform" v-if="data.id === -100"/>
            <JIcon :icon="DFT_ICONS.global" v-else-if="data.id === -1"/>
            <JIcon :icon="DFT_ICONS.app" v-else-if="data.isApp"/>
            <JIcon
              :icon="DFT_ICONS.cloud" v-else-if="data.func_store === 1"
              v-tippy="{ arrow: true }"
              content="云函数实现"
            />
            <JIcon
              :icon="DFT_ICONS.codepen"
              v-else-if="data.func_store === 2"
              v-tippy="{ arrow: true }"
              content="专属函数实现"></JIcon>
            <JIcon
              :icon="DFT_ICONS.fileLocal"
              v-else-if="data.func_store === 3"
              v-tippy="{ arrow: true }"
              content="任务文件"/>
          </span>
          <span
            style="text-overflow: ellipsis;overflow: hidden;padding-right: 20px;"
            v-tippy="{ arrow: true }"
            :content="getNodeTip(data)">{{ data.name }}
          </span>

          <div
            @click.stop="empty"
            v-if="hasTaskCreatePermission(data) || hasTaskEdit(data)">
            <el-dropdown
              trigger="click"
              placement="bottom-start"
              class="absolute right-0"
              @command="handleTreeCommand($event, data)">
              <JIcon
                :icon="DFT_ICONS.more"
                class="btn-more"
                v-tippy="{ arrow: true }"
                content="更多操作"/>
              <template #dropdown>
                <el-dropdown-menu>
                  <template v-if="hasTaskCreatePermission(data)">
                    <el-dropdown-item command="create">
                      <JIcon
                        :icon="DFT_ICONS.add"
                      />注册任务
                    </el-dropdown-item>
                  </template>
                  <template v-if="hasTaskEdit(data)">
                    <el-dropdown-item command="edit">
                      <JIcon
                        :icon="DFT_ICONS.edit"
                      />修改</el-dropdown-item>
                    <el-dropdown-item command="remove">
                      <JIcon
                        :icon="DFT_ICONS.delete"
                      />删除</el-dropdown-item>
                  </template>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </span>
      </template>
    </el-tree>

    <el-drawer
      :title="formModuleWinName"
      v-model="formModuleWinShow"
      :append-to-body="true"
      class="wf-node-prop-drawer"
      size="96%"
      :before-close="handleClose">
      <FormTask
        v-if="formModuleWinShow"
        :app-id="formAppId"
        :type="formType"
        :task="formTask"
        @close="handleClose"
      />
    </el-drawer>
  </el-scrollbar>
</template>

<script setup>
import {ref, onMounted, watch, nextTick} from 'vue';
import _ from 'lodash';
import FormTask from './form-task.vue';
import {DFT_ICONS} from "@jzl/icons";
import {isTask, hasTaskCreatePermission, hasTaskEdit, isPlatform, isGlobal} from '../func/common.js';
import {api} from "@jzl/api";
import {$jui} from '@jzl/utils'

const props = defineProps({
  appId: [String, Number]
});

const emit = defineEmits(['select']);

const apps = ref([]);
const items = ref([]);
const app = ref(null);
const loading = ref(false);
const currentData = ref({});
const expandedKeys = ref([]);
const formModuleWinName = ref('');
const formModuleWinShow = ref(false);
const type = ref(3);
const formAppId = ref(-1);
const formType = ref(3);
const formTask = ref(null);
const treeSetting = ref({
  children: 'subs',
  label: 'name',
  'icon-class': 'hello-icon'
});
const mbtreeRef = ref(null)

const init = async () => {
  await loadRoot();
  let ids = _.map(apps.value, 'id');
  expandedKeys.value = ids;
};

const empty = () => {
};

const refreshCurrentNode = async (key) => {
  await init();

  let id = _.get(currentData.value, 'id');

  if (key) {
    id = key;
  }

  expandedKeys.value = [id];

  let data = $utils.getTreeData(apps.value, 'id', key, 'subs');

  if (data) {
    handleClick(data);
  }
};

const loadRoot = async () => {
  loading.value = true;

  let appsData = await loadApps();
  let tasks = await api.task.getTasks();

  tasks = _.map(tasks, fm => {
    fm.name = _.get(fm, 'task_name');
    return fm;
  });

  _.each(appsData, appData => {
    let subs = [];

    // 全局
    if (appData.id === -100) {
      subs = _.filter(tasks, {type: 1});
    } else if (appData.id === -1) {
      subs = _.filter(tasks, {type: 2});
    } else {
      subs = _.filter(tasks, {app_id: appData.id});
    }

    appData.subs = subs;
  });

  apps.value = appsData;
  loading.value = false;
};

const loadApps = async () => {
  let ret = await api.admin.getMyApps();
  let myApps = _.get(ret, 'apps', []);
  let appsData = [{
    nodeType: 'plat',
    name: '平台内置',
    id: -100
  }, {
    nodeType: 'system',
    name: '项目全局',
    id: -1
  }];

  let xMyApps = _.map(myApps, app => {
    return {
      nodeType: 'app',
      name: `${_.get(app, 'group_name')}`,
      id: _.get(app, 'group_id'),
      isApp: true
    };
  });

  appsData = _.concat(appsData, xMyApps);

  if (props.appId) {
    appsData = _.filter(appsData, ap => {
      return ap && (ap.id === props.appId || ap.id < 0);
    });
  }

  return appsData;
};

const handleClick = (data, node, ele) => {
  currentData.value = data;
  if (!data) return;

  if (mbtreeRef.value.store.nodesMap && mbtreeRef.value.store.nodesMap[data.id]) {
    mbtreeRef.value.store.nodesMap[data.id].expanded = true;
  }

  emit("select", data);
};

const handleClearSelect = () => {
  try {
    mbtreeRef.value.setCurrentNode({id: null});
  } catch (e) {
  }
};

const handleShowCreateModule = () => {
  // console.log('=========>>>>>>')
  if (!currentData.value || !hasTaskCreatePermission(currentData.value)) {
    return;
  }

  let name = _.get(currentData.value, 'name');
  let fAppId = -1;
  let ffType = 3;

  if (isPlatform(currentData.value)) {
    ffType = 1;
  } else if (isGlobal(currentData.value)) {
    ffType = 2;
  } else {
    fAppId = _.get(currentData.value, "id");
  }

  formAppId.value = fAppId;
  formType.value = ffType;
  formTask.value = null;
  formModuleWinName.value = `【${name}】下注册任务`;
  formModuleWinShow.value = true;
};

const handleShowEdit = () => {
  let name = _.get(currentData.value, 'name');

  if (isTask(currentData.value)) {
    formTask.value = currentData.value;
    formAppId.value = -1;
    formType.value = null;
    formModuleWinShow.value = true;
    formModuleWinName.value = `修改任务【${name}】`;
  }
};

const handleShowDelete = () => {
  let dt = currentData.value;
  if (!dt) return;
  if (!isTask(dt)) return;

  let msg = `确定删除任务【${dt.name}】?`;
  $jui.confirm(msg).then(async () => {
    let ret = await api.task.remove(dt.task_id);
    let key = '';

    if (ret) {
      if (ret.app_id > 0) {
        key = ret.app_id;
      } else if (ret.project_id > 0) {
        key = -1;
      } else {
        key = -100;
      }
    }

    refreshCurrentNode(key);
  }).catch(e => {
  });
};

const handleTreeCommand = (cmd, data) => {
  currentData.value = data;

  if (cmd === 'create') {
    handleShowCreateModule();
  } else if (cmd === 'edit') {
    handleShowEdit();
  } else if (cmd === 'remove') {
    handleShowDelete();
  }
};

const handleClose = (isUpdate) => {
  formModuleWinShow.value = false;

  if (isUpdate) {
    refreshCurrentNode();
  }
};

const getNodeTip = (data) => {
  let tip = _.get(data, "name");
  let code = _.get(data, "task_code");

  if (code) {
    tip += `(${code})`;
  }

  return tip;
};

onMounted(() => {
  init();
});

watch(() => props.appId, () => {
  init();
});
</script>
